package com.bicon.botu.finance.wallet.service;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.bicon.botu.core.base.common.BusinessException;
import com.bicon.botu.core.base.common.Constants;
import com.bicon.botu.core.base.common.entity.BaseResult;
import com.bicon.botu.core.base.common.utils.EncryptionUtil;
import com.bicon.botu.core.base.common.utils.JsonUtil;
import com.bicon.botu.core.base.common.utils.StringUtils;
import com.bicon.botu.core.base.repository.redis.RedisHandler;
import com.bicon.botu.finance.payment.rpc.service.PaymentRpcService;
import com.bicon.botu.finance.wallet.common.FinanceConstants;
import com.bicon.botu.finance.wallet.common.WalletConstants;
import com.bicon.botu.finance.wallet.entity.FinancialAccount;
import com.bicon.botu.finance.wallet.entity.Wallet;
import com.bicon.botu.finance.wallet.entity.WalletDetail;
import com.bicon.botu.finance.wallet.handler.WalletHandler;
import com.bicon.botu.mall.component.rpc.service.InformationRpcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: 宋旭
 * @Date: Created in 11:21 2017/6/21/021
 */
@Slf4j
@Service
@Transactional
public class WalletService {

    @Autowired
    private PaymentRpcService paymentRpc;

    @Autowired
    private InformationRpcService informationRpc;

    @Autowired
    WalletHandler walletHandler;

    @Autowired
    FinancialAccountService financialAccountService;

    @Autowired
    RedisHandler redisHandler;

    @Value("${payPassword.errorTimes}")
    int errorTimes;
    /**
     * 激励活动-增加余额
     *
     * @param userId
     * @param money
     * @param subjects
     * @return
     */
    public BaseResult addBalance(String appId, String module, String business, String userId, double money, String subjects) {
        if (money <= 0) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        //初始化变量
        boolean result;
        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        //查找账户
        Wallet wallet = selectWalletByUserId(userId);
        if (null == wallet || StringUtils.isBlank(wallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
        }
        //验证余额与余额加密字段是否相等
        if (!wallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(wallet.getMoney().toString()))) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8001, WalletConstants.RESPONSE_MESSAGE_8001);
        }
        //根据科目类型修改余额，并保存
        BigDecimal totalMoney;
        //收入、充值增加余额
        if (FinanceConstants.WALLET_SUBJECTS_INCOME.equals(subjects) || FinanceConstants.WALLET_SUBJECTS_RECAHRGE.equals(subjects)) {
            totalMoney = wallet.getMoney().add(bigMoney);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        wallet.setMoney(totalMoney);
        wallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
        wallet.preUpdate();
        result = wallet.updateById();
        if (!result) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        //保存明细
        WalletDetail walletDetail = addWalletDetail(appId, module, business, FinanceConstants.WALLET_FINANCIAL_TYPE_TASK, userId, wallet.getId(), bigMoney, subjects, FinanceConstants.WALLET_CHILD_SUBJECTS_TASK, null, null, FinanceConstants.WALLET_STATE_SUCCESS, null, null, "激励任务");
        if (null != walletDetail) {
            //修改缓存中的余额
            walletHandler.cacheBalance(userId, totalMoney);
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
    }

    /**
     * 增加余额
     *
     * @param userId        用户id
     * @param money         金额
     * @param subjects      主题分类
     * @param financialType 支付类型  0:余额，1：支付宝，2：微信，3：银联
     * @param subjectChild  主题分类子项
     * @param remark        备注
     * @return
     */
    public BaseResult addBalanceV2(String appId, String module, String business, String userId, double money, String subjects, String financialType, String subjectChild, String remark) {
        if (money <= 0) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        //初始化变量
        boolean result;
        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        //查找账户
       Wallet wallet = selectWalletByUserId(userId);
         if (null == wallet) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_602, WalletConstants.RESPONSE_MESSAGE_602);
        }
        //验证余额与余额加密字段是否相等
        if (!wallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(wallet.getMoney().toString()))) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8001, WalletConstants.RESPONSE_MESSAGE_8001);
        }
        //根据科目类型修改余额，并保存
        BigDecimal totalMoney;
        //收入、充值增加余额
        if (FinanceConstants.WALLET_SUBJECTS_INCOME.equals(subjects) || FinanceConstants.WALLET_SUBJECTS_RECAHRGE.equals(subjects)) {
            totalMoney = wallet.getMoney().add(bigMoney);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        wallet.setMoney(totalMoney);
        wallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
        wallet.preUpdate();
        result = wallet.updateById();
        if (!result) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        //保存明细
        WalletDetail walletDetail = addWalletDetail(appId, module, business, financialType, userId, wallet.getId(), bigMoney, subjects, subjectChild, null, null, FinanceConstants.WALLET_STATE_SUCCESS, null, null, remark);
        if (null != walletDetail) {
            //修改缓存中的余额
            walletHandler.cacheBalance(userId, totalMoney);
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
    }

    /**
     * 转账
     *
     * @param fromUserId 转账人
     * @param money      金额
     * @param toUserId   接收人
     * @param payPwd     支付密码
     * @param remark     备注
     * @param payType    钱包0、支付宝1、微信2
     * @param code       传APP的标识 BOTU
     * @return
     */
    public BaseResult transfer(String appId, String module, String business, double money, String fromUserId, String toUserId, String payPwd, String remark, String payType, String code) {
        //参数非空校验
        if (StringUtils.isBlank(fromUserId) || StringUtils.isBlank(toUserId) || StringUtils.isBlank(payPwd) || money < 0.01) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_401, "参数不正确");
        }
        //转账人参数校验
        Wallet formWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", fromUserId));
        if (null == formWallet || StringUtils.isBlank(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
        }
        if (!EncryptionUtil.getMD5Str(payPwd).equals(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8011, "支付密码错误");
        }
        //【余额支付】
        if (FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //验证余额与余额加密字段是否相等
            if (!formWallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(formWallet.getMoney().toString()))) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8012, "钱包余额异常");
            }
            //转账金额是否大于余额
            if (formWallet.getMoney().compareTo(BigDecimal.valueOf(money)) < 0) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8013, "钱包余额不足");
            }
        }

        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        String orderNo = StringUtils.createOrderNo();
        String payOrderNo = StringUtils.createOrderNo() + StringUtils.createRandomNo();
        Map map = new HashMap<>();
        BaseResult baseResult = new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        String state = FinanceConstants.WALLET_STATE_ING;
        if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //【支付宝、微信支付】
            //发送支付中心下单接口rpc
            BaseResult baseResultStr = paymentRpc.launchPay(code, payOrderNo, "转账", code + "转账订单", String.valueOf(money), payType, "备用参数");
            log.info("【调用转账支付rpc结果】：" + JSONUtils.toJSONString(baseResultStr));
            if (baseResultStr != null) {
                if (baseResultStr.getCode() != Constants.RESPONSE_CODE_200) {
                    return baseResultStr;
                }
                String payInfo = baseResultStr.getData().toString();
                map.put("payInfo", payInfo);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_500, "转账rpc调用失败");
            }
        } else {
            //【余额支付】
            state = FinanceConstants.WALLET_STATE_RECEIVABLE;
            //修改【转账人】db中的余额
            BigDecimal totalMoney = formWallet.getMoney().subtract(bigMoney);
            formWallet.setMoney(totalMoney);
            formWallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
            formWallet.preUpdate();
            boolean result = formWallet.updateById();
            if (!result) {
                return new BaseResult(Constants.RESPONSE_CODE_500, "钱包余额减去转账金额操作失败");
            }
            //修改【转账人】缓存中的余额
            walletHandler.cacheBalance(fromUserId, totalMoney);
            Map<String,Object> mapMessage=messageInfo("付款成功","转账",toUserId,money,payType,orderNo,"1","1");

            informationRpc.save(appId,"finance","transaction",fromUserId,"金融-交易信息",JSONObject.toJSONString(mapMessage),"您刚刚支付了￥"+money+"元","1");
        }

        //记录【转账人】转账交易记录
        WalletDetail walletDetailA = new WalletDetail();
        walletDetailA.preInsert();
        walletDetailA.setAppId(appId);
        walletDetailA.setModule(module);
        walletDetailA.setBusiness(business);
        walletDetailA.setUserId(fromUserId);
        walletDetailA.setOtherUserId(toUserId);
        walletDetailA.setWalletId(formWallet.getId());
        walletDetailA.setSubjects(FinanceConstants.WALLET_SUBJECTS_PAY);//支出
        walletDetailA.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_TRANSFER);//转账
        walletDetailA.setMoney(bigMoney);//金额
        walletDetailA.setFinancialType(payType);
        walletDetailA.setOrderNo(orderNo);
        walletDetailA.setPayOrderNo(payOrderNo);
        walletDetailA.setState(state);//余额支付则为待收款，支付宝微信支付则为交易中
        walletDetailA.setRemark(remark);
        walletDetailA.insert();

        //记录【接收人】转账交易记录
        WalletDetail walletDetailB = new WalletDetail();
        walletDetailB.preInsert();
        walletDetailB.setAppId(appId);
        walletDetailB.setModule(module);
        walletDetailB.setBusiness(business);
        walletDetailB.setUserId(toUserId);
        walletDetailB.setOtherUserId(fromUserId);
        walletDetailB.setSubjects(FinanceConstants.WALLET_SUBJECTS_INCOME);//收入
        walletDetailB.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_TRANSFER);//转账
        walletDetailB.setMoney(bigMoney);//金额
        walletDetailB.setFinancialType(payType);
        walletDetailB.setOrderNo(orderNo);
        walletDetailB.setPayOrderNo(payOrderNo);
        walletDetailB.setState(state);
        walletDetailB.setRemark(remark);
        walletDetailB.insert();

        map.put("order", walletDetailA);
        baseResult.setData(map);
        return baseResult;
    }

    /**
     * 转账
     *
     * @param fromUserId 转账人
     * @param money      金额
     * @param toUserId   接收人
     * @param payPwd     支付密码
     * @param remark     备注
     * @param payType    钱包0、支付宝1、微信2
     * @param code       传APP的标识 BOTU
     * @return
     */
    public BaseResult gratuity(String module,String business, String fromUserId, double money, String toUserId, String payPwd, String remark, String payType, String code) {
        //参数非空校验
        if (StringUtils.isBlank(fromUserId) || StringUtils.isBlank(toUserId) || StringUtils.isBlank(payPwd) || money < 0.01) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_401, "参数不正确");
        }
        //转账人参数校验
        Wallet formWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", fromUserId));
        //接收人参数校验
        Wallet toWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", toUserId));
        if (null == formWallet || StringUtils.isBlank(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
        }
        if (!EncryptionUtil.getMD5Str(payPwd).equals(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8011, "支付密码错误");
        }
        //【余额支付】
        if (FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //验证余额与余额加密字段是否相等
            if (!formWallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(formWallet.getMoney().toString()))) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8012, "钱包余额异常");
            }
            //转账金额是否大于余额
            if (formWallet.getMoney().compareTo(BigDecimal.valueOf(money)) < 0) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8013, "钱包余额不足");
            }
        }

        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        String orderNo = StringUtils.createOrderNo();
        String payOrderNo = StringUtils.createOrderNo() + StringUtils.createRandomNo();
        Map map = new HashMap<>();
        BaseResult baseResult = new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        String state = FinanceConstants.WALLET_STATE_ING;
        if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //【支付宝、微信支付】
            //发送支付中心下单接口rpc
            BaseResult baseResultStr = paymentRpc.launchPay(code, payOrderNo, "转账", code + "转账订单", String.valueOf(money), payType, "备用参数");
            log.info("【调用转账支付rpc结果】：" + baseResultStr);
            if (baseResultStr != null) {
                if (baseResultStr.getCode() != Constants.RESPONSE_CODE_200) {
                    return baseResultStr;
                }
                String payInfo = baseResultStr.getData().toString();
                map.put("payInfo", payInfo);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_500, "转账rpc调用失败");
            }
        } else {
            //【余额支付】
            state = FinanceConstants.WALLET_STATE_RECEIVABLE;
            //修改【转账人】db中的余额
            BigDecimal totalMoney = formWallet.getMoney().subtract(bigMoney);
            formWallet.setMoney(totalMoney);
            formWallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
            formWallet.preUpdate();
            boolean result = formWallet.updateById();
            BigDecimal toUserMoney = toWallet.getMoney().add(bigMoney);
            toWallet.setMoney(toUserMoney);
            toWallet.setMoneyMD5(EncryptionUtil.getMD5Str(toUserMoney.toString()));
            toWallet.preUpdate();
            boolean resultA=toWallet.updateById();
            if (!result||!resultA) {
                return new BaseResult(Constants.RESPONSE_CODE_500, "钱包余额减去转账金额操作失败");
            }
            //修改【转账人】缓存中的余额
            walletHandler.cacheBalance(fromUserId, totalMoney);
            walletHandler.cacheBalance(toUserId,toUserMoney);
        }

        //记录【转账人】转账交易记录
        WalletDetail walletDetailA = new WalletDetail();

        walletDetailA.preInsert();
        walletDetailA.setAppId("botu");
        walletDetailA.setModule(module);
        walletDetailA.setBusiness(business);
        walletDetailA.setUserId(fromUserId);
        walletDetailA.setOtherUserId(toUserId);
        walletDetailA.setWalletId(formWallet.getId());
        walletDetailA.setSubjects(FinanceConstants.WALLET_SUBJECTS_PAY);//支出
        walletDetailA.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_APPRECIATE);//转账
        walletDetailA.setMoney(bigMoney);//金额
        walletDetailA.setFinancialType(payType);
        walletDetailA.setOrderNo(orderNo);
        walletDetailA.setPayOrderNo(payOrderNo);
        walletDetailA.setState(state);//余额支付则为待收款，支付宝微信支付则为交易中
        walletDetailA.setRemark(remark);
        walletDetailA.insert();

        //记录【接收人】转账交易记录
        WalletDetail walletDetailB = new WalletDetail();
        walletDetailB.preInsert();
        walletDetailB.setAppId("botu");
        walletDetailB.setModule(module);
        walletDetailB.setBusiness(business);
        walletDetailB.setUserId(toUserId);
        walletDetailB.setOtherUserId(fromUserId);
        walletDetailB.setSubjects(FinanceConstants.WALLET_SUBJECTS_INCOME);//收入
        walletDetailB.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_APPRECIATE);//转账
        walletDetailB.setMoney(bigMoney);//金额
        walletDetailB.setFinancialType(payType);
        walletDetailB.setOrderNo(orderNo);
        walletDetailB.setPayOrderNo(payOrderNo);
        walletDetailB.setState(state);
        walletDetailB.setRemark(remark);
        walletDetailB.insert();

        map.put("order", walletDetailA);
        baseResult.setData(map);
        return baseResult;
    }

    /**
     * 订单支付
     *
     * @param fromUserId 发送人用户id
     * @param money      金额
     * @param toUserId   接收商铺id
     * @param payPwd     支付密码
     * @param remark     备注
     * @param payType    支付类型 类型 0:余额，1：支付宝，2：微信，3：银联
     * @param code       BOTU
     * @return
     */
    public BaseResult gratuity1(String module,String business, String fromUserId, double money, String toUserId, String payPwd, String remark, String payType, String code) {
        //参数非空校验
        if (StringUtils.isBlank(fromUserId) || StringUtils.isBlank(toUserId) || money < 0.01) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_401, "参数不正确");
        }
        //转账人参数校验
        Wallet formWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", fromUserId));
        //接收人参数校验
        Wallet toWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", toUserId));


        //【余额支付】
        if (FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            if (StringUtils.isBlank(payPwd)){
                return new BaseResult(WalletConstants.RESPONSE_CODE_401, "参数不正确");
            }

            if (null == formWallet || StringUtils.isBlank(formWallet.getPayPassword())) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
            }

            if (!EncryptionUtil.getMD5Str(payPwd).equals(formWallet.getPayPassword())) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8011, "支付密码错误");
            }
            //验证余额与余额加密字段是否相等
            if (!formWallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(formWallet.getMoney().toString()))) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8012, "钱包余额异常");
            }
            //转账金额是否大于余额
            if (formWallet.getMoney().compareTo(BigDecimal.valueOf(money)) < 0) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8013, "钱包余额不足");
            }
        }

        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        String orderNo = StringUtils.createOrderNo();
        String payOrderNo = StringUtils.createOrderNo() + StringUtils.createRandomNo();
        Map map = new HashMap<>();
        BaseResult baseResult = new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        String state = FinanceConstants.WALLET_STATE_ING;
        if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //【支付宝、微信支付】
            //发送支付中心下单接口rpc
            BaseResult baseResultStr = paymentRpc.launchPay(code, payOrderNo, "转账", code + "转账订单", String.valueOf(money), payType, "备用参数");
            log.info("【调用转账支付rpc结果】：" + baseResultStr);
            if (baseResultStr != null) {
                if (baseResultStr.getCode() != Constants.RESPONSE_CODE_200) {
                    return baseResultStr;
                }
                String payInfo = baseResultStr.getData().toString();
                map.put("payInfo", payInfo);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_500, "转账rpc调用失败");
            }
        } else {
            //【余额支付】
            state = FinanceConstants.WALLET_STATE_RECEIVABLE;
            //修改【转账人】db中的余额
            BigDecimal totalMoney = formWallet.getMoney().subtract(bigMoney);
            formWallet.setMoney(totalMoney);
            formWallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
            formWallet.preUpdate();
            boolean result = formWallet.updateById();
            BigDecimal toUserMoney = toWallet.getMoney().add(bigMoney);
            toWallet.setMoney(toUserMoney);
            toWallet.setMoneyMD5(EncryptionUtil.getMD5Str(toUserMoney.toString()));
            toWallet.preUpdate();
            boolean resultA=toWallet.updateById();
            if (!result||!resultA) {
                return new BaseResult(Constants.RESPONSE_CODE_500, "钱包余额减去转账金额操作失败");
            }
            //修改【转账人】缓存中的余额
            walletHandler.cacheBalance(fromUserId, totalMoney);
            walletHandler.cacheBalance(toUserId,toUserMoney);
        }

        //记录【转账人】转账交易记录
        WalletDetail walletDetailA = new WalletDetail();

        walletDetailA.preInsert();
        walletDetailA.setAppId("botu");
        walletDetailA.setModule(module);
        walletDetailA.setBusiness(business);
        walletDetailA.setUserId(fromUserId);
        walletDetailA.setOtherUserId(toUserId);
        walletDetailA.setWalletId(formWallet.getId());
        walletDetailA.setSubjects(FinanceConstants.WALLET_SUBJECTS_PAY);//支出
        walletDetailA.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_APPRECIATE);//转账
        walletDetailA.setMoney(bigMoney);//金额
        walletDetailA.setFinancialType(payType);
        walletDetailA.setOrderNo(orderNo);
        walletDetailA.setPayOrderNo(payOrderNo);
        walletDetailA.setState(state);//余额支付则为待收款，支付宝微信支付则为交易中
        walletDetailA.setRemark(remark);
        walletDetailA.insert();

        //记录【接收人】转账交易记录
        WalletDetail walletDetailB = new WalletDetail();
        walletDetailB.preInsert();
        walletDetailB.setAppId("botu");
        walletDetailB.setModule(module);
        walletDetailB.setBusiness(business);
        walletDetailB.setUserId(toUserId);
        walletDetailB.setOtherUserId(fromUserId);
        walletDetailB.setSubjects(FinanceConstants.WALLET_SUBJECTS_INCOME);//收入
        walletDetailB.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_APPRECIATE);//转账
        walletDetailB.setMoney(bigMoney);//金额
        walletDetailB.setFinancialType(payType);
        walletDetailB.setOrderNo(orderNo);
        walletDetailB.setPayOrderNo(payOrderNo);
        walletDetailB.setState(state);
        walletDetailB.setRemark(remark);
        walletDetailB.insert();

        map.put("order", walletDetailA);
        baseResult.setData(map);
        return baseResult;
    }
















    /**
     * 转账确认收款操作
     *
     * @param userId  用户id
     * @param orderNo 订单号
     * @return
     */
    public BaseResult transferConfirm(String userId, String orderNo) {
        //校验是否转给本人，订单号是否真实，是否是转账订单，是否是待收款状态
        WalletDetail walletDetail = new WalletDetail();
        walletDetail = walletDetail.selectOne(new EntityWrapper()
                .eq("user_id", userId)
                .eq("order_no", orderNo)
                .eq("subjects", FinanceConstants.WALLET_SUBJECTS_INCOME)
                .eq("subjects_child", FinanceConstants.WALLET_CHILD_SUBJECTS_TRANSFER)
                .eq("logic_delete", WalletConstants.DEL_LOGIC_NORMAL));
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -1);
        if (walletDetail == null) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8003, WalletConstants.RESPONSE_MESSAGE_8003);
        }
        if (walletDetail.getCreateDate().before(calendar.getTime())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8004, WalletConstants.RESPONSE_MESSAGE_8004);
        }
        if (FinanceConstants.WALLET_STATE_ING.equals(walletDetail.getState())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8005, WalletConstants.RESPONSE_MESSAGE_8005);
        }
        if (FinanceConstants.WALLET_STATE_SUCCESS.equals(walletDetail.getState())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8006, WalletConstants.RESPONSE_MESSAGE_8006);
        }
        if (FinanceConstants.WALLET_STATE_FAIL.equals(walletDetail.getState())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8007, WalletConstants.RESPONSE_MESSAGE_8007);
        }
        if (FinanceConstants.WALLET_STATE_CANCEL.equals(walletDetail.getState())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8008, WalletConstants.RESPONSE_MESSAGE_8008);
        }
        if (FinanceConstants.WALLET_STATE_RECEIVABLE.equals(walletDetail.getState())) {
            //增加数据库中余额
            Wallet wallet = new Wallet();
            wallet = wallet.selectOne(new EntityWrapper().eq("user_id", userId));
            if (wallet == null) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
            }
            BigDecimal totalMoney = wallet.getMoney().add(walletDetail.getMoney());
            wallet.setMoney(totalMoney);
            wallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
            wallet.setUpdateDate(new Date());
            wallet.updateById();
            //增加缓存中余额
            //修改【转账人】缓存中的余额
            walletHandler.cacheBalance(userId, wallet.getMoney());
            //修改两条转账记录状态为成功
            WalletDetail wd = new WalletDetail();
            wd.setState(FinanceConstants.WALLET_STATE_SUCCESS);
            wd.setUpdateDate(new Date());
            wd.update(new EntityWrapper().eq("order_no", orderNo));
            return new BaseResult(WalletConstants.RESPONSE_CODE_200, WalletConstants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8010, WalletConstants.RESPONSE_MESSAGE_8010);
        }
    }

    /**
     * 封装消息内容
     * @param fromUserId 用户id
     * @param money      金额
     * @param payType    支付方式
     * @param payOrderNo  订单号
     * @return
     */
    public Map<String,Object> messageInfo(String subject,String business, String fromUserId,double money,String payType,String payOrderNo,String tradeType,String tradeRecordType){
        Map<String,Object> map = new HashMap<>();
        JSONArray jsonArray = new JSONArray();
        JSONObject jsonObject = new JSONObject();
        String userJson= redisHandler.getGlobalRedisTemplate().getStringValue(WalletConstants.BOTU_USER_USER_INFO,fromUserId);
        JSONObject objectUser= new JSONObject();
        if(null!=userJson){
            objectUser=   JSONObject.parseObject(userJson);
        }
        jsonArray.add(subject);
        jsonArray.add(business);
        map.put("mainTitle","￥"+money);
        map.put("attributes",jsonArray);
        map.put("tradeType",tradeType);
        jsonObject.put("transferState",FinanceConstants.WALLET_STATE_SUCCESS);
        jsonObject.put("from",payType);
        jsonObject.put("orderNo",payOrderNo);
        jsonObject.put("friendNick",objectUser.getString("nickName")) ;
        jsonObject.put("messageFrom",objectUser.getString("phone"));
        jsonObject.put("tradeRecordType",tradeRecordType);
        map.put("businessId",jsonObject);
        return map;
    }




    /**
     * 根据用户id查找余额
     *
     * @param userId
     * @return
     */
    public BaseResult selectBalance(String userId) {
        String balance = walletHandler.getBalance(userId);
        if (null == balance) {
            Wallet wallet = selectWalletByUserId(userId);
            if (null == wallet) {
                return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, wallet.getMoney().toString());
            }
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, balance);
        }
    }

    /**
     * 根据用户id查找余额
     *
     * @param userId
     * @return
     */
    public String selectBalanceString(String userId) {
        String balance = walletHandler.getBalance(userId);
        if (null == balance) {
            Wallet wallet = selectWalletByUserId(userId);
            if (null == wallet) {
                return Constants.FAILURE;
            } else {
                return wallet.getMoney().toString();
            }
        } else {
            return balance;
        }
    }

    /**
     * 根据用户id查密码是否为空
     *
     * @param userId
     * @return
     */
    public BaseResult selectPaypwd(String userId) {
        Wallet wallet = selectWalletByUserId(userId);
        if (null == wallet) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        } else {
            if (StringUtils.isNotBlank(wallet.getPayPassword())) {
                return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, WalletConstants.FINANCIAL_PWD_YES);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, WalletConstants.FINANCIAL_PWD_NO);
            }
        }
    }

    /**
     * 根据用户id查找wallet,不存在则新建
     *
     * @param userId
     * @return
     */
    public Wallet selectWalletByUserId(String userId) {
        BigDecimal bigMoney = new BigDecimal(Double.valueOf(0d)).setScale(2);
        //构建查询参数
        Wallet entity = new Wallet();
        entity = entity.selectOne(new EntityWrapper<Wallet>().eq("user_id", userId));
        if (null == entity) {
            //如果为空则新建
            Wallet wallet = new Wallet();
            wallet.setUserId(userId);
            wallet.setMoney(bigMoney);
            wallet.setMoneyMD5(EncryptionUtil.getMD5Str(bigMoney.toString()));
            wallet.setStatus(WalletConstants.WALLET_STATUS_ABLE);
            wallet.preInsert();
            boolean result = wallet.insert();
            if (result) {
                return wallet;
            } else {
                return null;
            }
        } else {
            return entity;
        }
    }
    /**
     * 根据老密码修改密码
     * @param userId
     * @param oldPwd
     * @param newPwd
     * @return
     */
    public BaseResult updatePaypasswordByPwd(String userId, String oldPwd, String newPwd) {
        if (StringUtils.isBlank(userId) || StringUtils.isBlank(oldPwd) || StringUtils.isBlank(newPwd)) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        Wallet entity = new Wallet().selectOne(new EntityWrapper<Wallet>().eq("user_id", userId)
                .eq("pay_password", EncryptionUtil.getMD5Str(oldPwd)));
        if (null == entity) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        entity.setPayPassword(EncryptionUtil.getMD5Str(newPwd));
        boolean result = entity.updateById();
        if (result) {
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
    }
    /**
     * 校验原密码
     *
     * @param userId
     * @param oldPwd
     * @return
     */
    public BaseResult checkOldPwd(String userId, String oldPwd) {
        String times = redisHandler.getLocalRedisTemplate().getStringValue(WalletConstants.BOTU_USER_PAYPASSWORD_ERRORTIMES, userId);
        int t = 0;
        if (StringUtils.isNotEmpty(times)) {
            t = Integer.parseInt(times);
            if (t < errorTimes) {
                t++;
                redisHandler.getLocalRedisTemplate().cacheStringValue(WalletConstants.BOTU_USER_PAYPASSWORD_ERRORTIMES, userId, t + "", 10 * 60);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_400, "原支付密码不正确，输入次数过多账户已锁定，请忘记密码找回或10分钟后重试");
            }
        } else {
            redisHandler.getLocalRedisTemplate().cacheStringValue(WalletConstants.BOTU_USER_PAYPASSWORD_ERRORTIMES, userId, "1", 10 * 60);
        }
        Wallet entity = new Wallet().selectOne(new EntityWrapper<Wallet>().eq("user_id", userId)
                .eq("pay_password", EncryptionUtil.getMD5Str(oldPwd)));
        if (null == entity) {
            if (t == errorTimes) {
                return new BaseResult(Constants.RESPONSE_CODE_400, "原支付密码不正确，输入次数过多账户已锁定，请忘记密码找回或10分钟后重试");
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_602, "原支付密码不正确");
            }
        } else {
            redisHandler.getLocalRedisTemplate().remove(WalletConstants.BOTU_USER_PAYPASSWORD_ERRORTIMES, userId);
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        }
    }

    /**
     * 设置支付密码
     *
     * @param userId
     * @param newPwd
     * @return
     */
    public BaseResult setPaypassword(String userId, String newPwd) {
        //查找账户
        Wallet wallet = selectWalletByUserId(userId);
        if (null == wallet) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        wallet.setPayPassword(EncryptionUtil.getMD5Str(newPwd));
        wallet.preUpdate();
        boolean result = wallet.updateById();
        if (result) {
            redisHandler.getLocalRedisTemplate().remove(WalletConstants.BOTU_USER_PAYPASSWORD_ERRORTIMES, userId);
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
    }

    /**
     * 保存明细
     *
     * @param userId
     * @param walletId
     * @param money
     * @param subject
     * @param state
     * @param financialId
     * @param remark
     * @return
     */
    public WalletDetail addWalletDetail(String appId, String module, String business, String type, String userId, String walletId, BigDecimal money, String subject, String subjectChild, String orderNo, String payOrderNo, String state, String financialId, String payInfo, String remark) {
        WalletDetail walletDetail = new WalletDetail();
        walletDetail.setAppId(appId);
        walletDetail.setModule(module);
        walletDetail.setBusiness(business);
        if (StringUtils.isNotBlank(type)) {
            walletDetail.setFinancialType(type);
        }
        walletDetail.setUserId(userId);
        walletDetail.setWalletId(walletId);
        walletDetail.setMoney(money);
        walletDetail.setSubjects(subject);
        if (StringUtils.isNotBlank(subjectChild)) {
            walletDetail.setSubjectsChild(subjectChild);
        }
        if (StringUtils.isNotBlank(orderNo)) {
            walletDetail.setOrderNo(orderNo);
        }
        if (StringUtils.isNotBlank(payOrderNo)) {
            walletDetail.setPayOrderNo(payOrderNo);
        }
        if (StringUtils.isNotBlank(state)) {
            walletDetail.setState(state);
        }
        if (StringUtils.isNotBlank(financialId)) {
            walletDetail.setFinancialId(financialId);
        }
        if (StringUtils.isNotBlank(payInfo)) {
            walletDetail.setPayInfo(payInfo);
        }
        if (StringUtils.isNotBlank(remark)) {
            walletDetail.setRemark(remark);
        }
        walletDetail.preInsert();
        walletDetail.insert();
        return walletDetail;
    }

    /**
     * 充值
     *
     * @param userId
     * @param type   交易类型（0:余额，1：支付宝，2：微信，3：银联）',
     * @param money  金额
     * @param code   应用code
     * @return
     */
    public BaseResult recahrge(String appId, String module, String business, String userId, String type, String money, String code) {
        Wallet wallet = selectWalletByUserId(userId);
        if (null == wallet) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        String orderNo = StringUtils.createOrderNo();
        String payOrderNo = StringUtils.createOrderNo() + StringUtils.createRandomNo();
        //发送rpc
        BaseResult baseResultStr = paymentRpc.launchPay(code, payOrderNo, "充值", code + "充值订单", String.valueOf(money), type, "备用参数");
        log.info("【调用支付充值rpc结果】：" + baseResultStr);
        if (baseResultStr != null) {
            if (baseResultStr.getCode() != Constants.RESPONSE_CODE_200) {
                return baseResultStr;
            }
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_500, "充值rpc调用失败");
        }
        //充值订单
        WalletDetail walletDetail = addWalletDetail(appId, module, business, type, userId, wallet.getId(), new BigDecimal(money), FinanceConstants.WALLET_SUBJECTS_RECAHRGE, FinanceConstants.WALLET_CHILD_SUBJECTS_RECAHRGE, orderNo, payOrderNo, FinanceConstants.WALLET_STATE_ING, null, (String) baseResultStr.getData(), "充值订单");
        if (baseResultStr == null || baseResultStr.getCode() != 200) {
            walletDetail.setState(FinanceConstants.WALLET_STATE_FAIL);
            walletDetail.updateById();
        }
        baseResultStr.setMessage(orderNo);
        return baseResultStr;
    }

    /**
     * 充值结果通知
     *
     * @param walletDetailId
     * @param state
     * @param reMoney
     * @return
     */
    public BaseResult recahrgeResult(String walletDetailId, String state, String reMoney) {
        WalletDetail walletDetail = new WalletDetail().selectById(walletDetailId);
        if (null == walletDetail) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        //金额对比
        if (0 != walletDetail.getMoney().compareTo(BigDecimal.valueOf(Double.valueOf(reMoney)))) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
        }
        walletDetail.setState(state);
        walletDetail.updateById();
        if (state.equals(FinanceConstants.WALLET_STATE_SUCCESS)) {
            Wallet wallet = new Wallet().selectById(walletDetail.getWalletId());
            if (null == wallet) {
                return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
            }
            //验证余额与余额加密字段是否相等
            if (!wallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(wallet.getMoney().toString()))) {
                return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401);
            }
            BigDecimal bigMoney = wallet.getMoney().add(walletDetail.getMoney());
            wallet.setMoney(bigMoney);
            wallet.setMoneyMD5(EncryptionUtil.getMD5Str(bigMoney.toString()));
            wallet.preUpdate();
            wallet.updateById();
        }
        return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
    }

    /**
     * 取消支付
     *
     * @param userId
     * @param orderNo
     * @return
     */
    public BaseResult cancelPay(String userId, String orderNo) {
        WalletDetail walletDetail = new WalletDetail();
        walletDetail = walletDetail.selectOne(new EntityWrapper().eq("user_id", userId).eq("order_no", orderNo).eq("state", FinanceConstants.WALLET_STATE_ING));
        if (walletDetail != null) {
            walletDetail.setState(FinanceConstants.WALLET_STATE_CANCEL);
            walletDetail.updateById();
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        } else {
            return new BaseResult(Constants.RESPONSE_CODE_400, "异常操作");
        }
    }
    /**
     * 确认订单
     */
    public String payConfirm(String userId, String orderNo, String payType, String resultInfo) {
        //验证订单信息
        //收入订单
        WalletDetail walletDetailIncome = new WalletDetail();
        //支出订单
        WalletDetail walletDetailPay = new WalletDetail();
        WalletDetail walletDetail = new WalletDetail();
        List<WalletDetail> list = walletDetail.selectList(new EntityWrapper().eq("order_no", orderNo));
        if (list != null) {
            if (list.size() > 0) {
                for (WalletDetail wd : list) {
                    if (FinanceConstants.WALLET_SUBJECTS_INCOME.equals(wd.getSubjects())) {
                        walletDetailIncome = wd;
                    } else if (FinanceConstants.WALLET_SUBJECTS_PAY.equals(wd.getSubjects())) {
                        walletDetailPay = wd;
                    } else if (FinanceConstants.WALLET_SUBJECTS_RECAHRGE.equals(wd.getSubjects())) {
                        walletDetailIncome = wd;
                    }
                    if (FinanceConstants.WALLET_CHILD_SUBJECTS_TRANSFER.equals(wd.getSubjectsChild()) && list.size() == 2) {
                        walletDetail.setState(FinanceConstants.WALLET_STATE_RECEIVABLE);
                    } else {
                        walletDetail.setState(FinanceConstants.WALLET_STATE_SUCCESS);
                    }
                }
            } else {
                return "fail";
            }
        }
        //支付结果校验
        if (FinanceConstants.WALLET_FINANCIAL_TYPE_ALIPAY.equals(payType)) {

        } else if (FinanceConstants.WALLET_FINANCIAL_TYPE_WECHAT.equals(payType)) {

        }
        //修改订单状态
        boolean flag = walletDetail.update(new EntityWrapper().eq("order_no", orderNo));
        if (flag && FinanceConstants.WALLET_SUBJECTS_RECAHRGE.equals(walletDetailIncome.getSubjects())) {
            //增加账户金额
            Wallet wallet = new Wallet();
            wallet = wallet.selectOne(new EntityWrapper().eq("user_id", walletDetailIncome.getUserId()));
            if (wallet == null) {
                return WalletConstants.RESPONSE_CODE_8000 + "";
            }
            BigDecimal money = wallet.getMoney().add(walletDetailIncome.getMoney());
            wallet.setMoney(money);
            wallet.setMoneyMD5(EncryptionUtil.getMD5Str(money.toString()));
            wallet.preUpdate();
            flag = wallet.updateById();
            if (flag) {
//              更新缓存中账户金额
                walletHandler.cacheBalance(userId, money);
            }
        }
        if (flag) {
            return "success";
        }
        return "fail";
    }

    /**
     * 校验支付信息
     *
     * @param userId  用户id
     * @param payType 支付类型
     * @param payPwd  支付密码
     * @param money   支付金额
     * @param code   app code
     * @param subject  类目
     * @param subjectChild 类目子项
     * @return
     */
    public BaseResult checkPayInfo(String appId, String module, String business, String userId, String payType, String payPwd, Double money, String code, String subject, String subjectChild) {

        //转账人参数校验
        Wallet formWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", userId));
        if (null == formWallet || StringUtils.isBlank(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8000, WalletConstants.RESPONSE_MESSAGE_8000);
        }
        log.info(EncryptionUtil.getMD5Str(payPwd));
        if (!EncryptionUtil.getMD5Str(payPwd).equals(formWallet.getPayPassword())) {
            return new BaseResult(WalletConstants.RESPONSE_CODE_8011, "支付密码错误");
        }
        //【余额支付】
        if (FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //验证余额与余额加密字段是否相等
            if (!formWallet.getMoneyMD5().equals(EncryptionUtil.getMD5Str(formWallet.getMoney().toString()))) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8012, "钱包余额异常");
            }
            //转账金额是否大于余额
            if (formWallet.getMoney().compareTo(BigDecimal.valueOf(money)) < 0) {
                return new BaseResult(WalletConstants.RESPONSE_CODE_8013, "钱包余额不足");
            }
        }
        BigDecimal bigMoney = new BigDecimal(Double.valueOf(money)).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        String orderNo = StringUtils.createOrderNo();
        String payOrderNo = StringUtils.createOrderNo() + StringUtils.createRandomNo();
        Map map = new HashMap<>();
        BaseResult baseResult = new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200);
        String state = FinanceConstants.WALLET_STATE_ING;
        if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)) {
            //【支付宝、微信支付】
            //发送支付中心下单接口rpc
            BaseResult baseResultStr = paymentRpc.launchPay(code, payOrderNo, "转账", code + "转账订单", String.valueOf(money), payType, "备用参数");
            log.info("【调用转账支付rpc结果】：" + baseResultStr);
            if (baseResultStr != null) {
                if (baseResultStr.getCode() != Constants.RESPONSE_CODE_200) {
                    return baseResultStr;
                }
                String payInfo = baseResultStr.getData().toString();
                map.put("payInfo", payInfo);
            } else {
                return new BaseResult(Constants.RESPONSE_CODE_500, "转账rpc调用失败");
            }
        } else {
            //【余额支付】
            state = FinanceConstants.WALLET_STATE_SUCCESS;
            //修改【转账人】db中的余额
            BigDecimal totalMoney = formWallet.getMoney().subtract(bigMoney);
            formWallet.setMoney(totalMoney);
            formWallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
            formWallet.preUpdate();
            boolean result = formWallet.updateById();
            if (!result) {
                return new BaseResult(Constants.RESPONSE_CODE_500, "钱包余额减去转账金额操作失败");
            }
            //修改【转账人】缓存中的余额
            walletHandler.cacheBalance(userId, totalMoney);

            Map<String,Object> mapMessage = messageInfo("付款成功","红包",userId,money,payType,payOrderNo,"2","1");
            informationRpc.save(appId,"finance","transaction",userId,"金融-交易信息",JSONObject.toJSONString(mapMessage),"您刚刚支付了￥"+money+"元","1");
        }
        // if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(payType)){
        WalletDetail detail = addWalletDetail(appId, module, business, payType, userId, formWallet.getId(), BigDecimal.valueOf(money), subject, subjectChild, orderNo, payOrderNo, state, null, null, "备注");

        // }
        map.put("detail",detail);
        return new BaseResult(WalletConstants.RESPONSE_CODE_200, WalletConstants.RESPONSE_MESSAGE_200, map);
    }


    /**
     * 退款添加
     *
     * @param money      金额
     * @param remark     备注
     * @param code       传APP的标识 BOTU
     * @return
     */
    public Map<String, WalletDetail> toRefund(String module,String business, String money, String remark, String code, String orderNo, String refundNo, String refundReason) {
        // 查询支出的记录
        WalletDetail walletDetail = new WalletDetail().selectOne(new EntityWrapper().eq("order_no", orderNo).eq("subjects",1).eq("logic_delete", WalletConstants.DEL_LOGIC_NORMAL));
        if (walletDetail == null) {
            throw new BusinessException(Constants.RESPONSE_CODE_500, "没有找到支付信息");
        }
        // 原交易付款人
        Wallet formWallet= new Wallet().selectOne(new EntityWrapper().eq("user_id", walletDetail.getUserId()));
        // 原交易收款人
        Wallet toWallet = new Wallet().selectOne(new EntityWrapper().eq("user_id", walletDetail.getOtherUserId()));

        BigDecimal bigMoney = new BigDecimal(money).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        Map map = new HashMap<>();
        String state = FinanceConstants.WALLET_STATE_ING;
        if (!FinanceConstants.WALLET_FINANCIAL_TYPE_BALANCE.equals(walletDetail.getFinancialType())) {
            //【支付宝、微信支付】
            //发送支付中心下单接口rpc
            BaseResult result = paymentRpc.refund(code, walletDetail.getPayOrderNo(), String.valueOf(money), walletDetail.getFinancialType(), refundNo, refundReason,walletDetail.getMoney().toString());
            log.info("【调用退款支付rpc结果】：" + JSONObject.toJSONString(result));
            BaseResult baseResult = null;
            if (result != null) {
                baseResult = result;
            }
            if (baseResult != null) {
                if (baseResult.getCode() != Constants.RESPONSE_CODE_200) {
                    throw new BusinessException(baseResult.getCode(), baseResult.getMessage());
                }
                String payInfo = baseResult.getData().toString();
                map.put("payInfo", payInfo);
            } else {
                throw new BusinessException(Constants.RESPONSE_CODE_500, "退款rpc调用失败");
            }
        }
        //扣除系统金额
        adminRefundUser(toWallet, formWallet , bigMoney);
        WalletDetail walletDetailB = setRefundWallet(module, business, walletDetail.getOtherUserId(), walletDetail.getUserId(), bigMoney, walletDetail.getFinancialType(), refundNo, walletDetail.getPayOrderNo(), state, remark);
        map.put("order", walletDetailB);
        return map;
    }

    //组装退款钱包明细实体
    private WalletDetail setRefundWallet(String module, String business, String toUserId, String fromUserId, BigDecimal bigMoney, String payType, String orderNo, String payOrderNo, String state, String remark) {
        //记录【接收人】转账交易记录
        WalletDetail walletDetailB = new WalletDetail();
        walletDetailB.preInsert();
        walletDetailB.setAppId("botu");
        walletDetailB.setModule(module);
        walletDetailB.setBusiness(business);
        walletDetailB.setUserId(toUserId);
        walletDetailB.setOtherUserId(fromUserId);
        walletDetailB.setSubjects(FinanceConstants.WALLET_SUBJECTS_REFUND);
        walletDetailB.setSubjectsChild(FinanceConstants.WALLET_CHILD_SUBJECTS_REFUND);
        walletDetailB.setMoney(bigMoney);
        walletDetailB.setFinancialType(payType);
        walletDetailB.setOrderNo(orderNo);
        walletDetailB.setPayOrderNo(payOrderNo);
        walletDetailB.setState(state);
        walletDetailB.setRemark(remark);
        walletDetailB.insert();
        return walletDetailB;
    }

    //减去系统和增加退款人的金额
    private void adminRefundUser(Wallet formWallet, Wallet toWallet, BigDecimal bigMoney) {
        //【余额支付】
        String state = FinanceConstants.WALLET_STATE_RECEIVABLE;
        //修改【转账人】db中的余额
        BigDecimal totalMoney = formWallet.getMoney().subtract(bigMoney);
        formWallet.setMoney(totalMoney);
        formWallet.setMoneyMD5(EncryptionUtil.getMD5Str(totalMoney.toString()));
        formWallet.preUpdate();
        boolean result = formWallet.updateById();
        BigDecimal toUserMoney = toWallet.getMoney().add(bigMoney);
        toWallet.setMoney(toUserMoney);
        toWallet.setMoneyMD5(EncryptionUtil.getMD5Str(toUserMoney.toString()));
        toWallet.preUpdate();
        boolean resultA=toWallet.updateById();
        if (!result||!resultA) {
            throw new BusinessException("钱包余额减去退款金额操作失败");
        }
        //修改【转账人】缓存中的余额
        walletHandler.cacheBalance(formWallet.getUserId(), totalMoney);
        walletHandler.cacheBalance(toWallet.getUserId(),toUserMoney);

    }

}
